% 
% @(#)real_String.m	1.3  3/16/88
%
import _RISCObject from "Builtins"
export _StringObject to "Builtins"

const _StringObject == immutable object _StringObject
  export getSignature, create, literal

  const StringType == immutable type StringType
    function getElement [index : Integer] -> [e : Character]
    function getSlice [lb : Integer, length : Integer] -> [a : String]
    function || [o : String] -> [r : String]
      % r <- self || o
    function asString -> [r : String]
      % r <- self
    function > [o : String] -> [r : Boolean]
      % r <- self > o
    function >= [o : String] -> [r : Boolean]
      % r <- self >= o
    function < [o : String] -> [r : Boolean]
      % r <- self < o
    function <= [o : String] -> [r : Boolean]
      % r <- self <= o
    function = [o : String] -> [r : Boolean]
      % r <- self = o
    function != [o : String] -> [r : Boolean]
      % r <- self != o
    function length -> [ r : Integer ]
    operation lowlevelsleazysetelement [Integer, Character]
  end StringType
  function getSignature -> [result : Signature]
    result <- StringType
  end getSignature
  
  function literal [rep : _RISCObject, offset : Integer, length : Integer] 
    -> [result : StringType]
    var strindex, repindex, limit : Integer
    if rep.lowerbound + offset + length > rep.upperbound + 1 then
      returnandfail
    end if
    result <- String.create[length]
    strindex <- 0
    repindex <- rep.lowerbound + offset
    
    limit <- length
    loop
      exit when strindex >= limit
      result.lowlevelsleazysetelement[strindex, rep(repindex)]
      strindex <- strindex + 1
      repindex <- repindex + 1
    end loop
  end literal
  operation create[length : Integer] -> [result : StringType]
    result <- immutable object aString
      export getElement, getSlice, ||, asString, >, >=, <, <=, =, !=, length,
	lowlevelsleazysetelement

      function getElement [index : Integer] -> [e : Character]
	primitive 011 [e] <- [index]
      end getElement
      function getSlice [lb : Integer, length : Integer] -> [a : String]
	primitive 111 [a] <- [lb, length]
      end getSlice
      function || [o : String] -> [r : String]
	primitive 211 [r] <- [o]
      end ||
      function asString -> [r : String]
	primitive 311 [r] <- []
      end asString
      function > [o : String] -> [r : Boolean]
	primitive 411 [r] <- [o]
      end >
      function >= [o : String] -> [r : Boolean]
	primitive 511 [r] <- [o]
      end >=
      function < [o : String] -> [r : Boolean]
	primitive 611 [r] <- [o]
      end <
      function <= [o : String] -> [r : Boolean]
	primitive 711 [r] <- [o]
      end <=
      function = [o : String] -> [r : Boolean]
	primitive 811 [r] <- [o]
      end =
      function != [o : String] -> [r : Boolean]
	primitive 911 [r] <- [o]
      end !=
      function length -> [ r : Integer ]
	primitive 1011 [r] <- []
      end length
      operation lowlevelsleazysetelement [i : Integer, c : Character]
	primitive 1111 [] <- [i, c]
      end lowlevelsleazysetelement
    end aString
  end create
end _StringObject
